<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Headings</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
	tex: {
		inlineMath: '$', '$'], ['\\(', '\\)'
	},
	svg: {
		fontCache: 'global'
	}
};
</script>
<script type="text/javascript" id="MathJax-script" async
	src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>

<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Headings' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inbuildn.html">Inbuild Modules</a></li><li><a href="index.html">supervisor</a></li><li><a href="index.html#6">Chapter 6: Inform Source Text</a></li><li><b>Headings</b></li></ul></div>
<p class="purpose">To keep track of the hierarchy of headings and subheadings found in the source text.</p>

<ul class="toc"><li><a href="6-hdn.html#SP1">&#167;1. The hierarchy</a></li><li><a href="6-hdn.html#SP4">&#167;4. Heading trees</a></li><li><a href="6-hdn.html#SP6">&#167;6. Heading metadata</a></li><li><a href="6-hdn.html#SP8">&#167;8. Declarations</a></li><li><a href="6-hdn.html#SP14">&#167;14. The heading tree</a></li><li><a href="6-hdn.html#SP16">&#167;16. Verifying the heading tree</a></li><li><a href="6-hdn.html#SP17">&#167;17. Falling under headings</a></li><li><a href="6-hdn.html#SP18">&#167;18. Miscellaneous other services</a></li><li><a href="6-hdn.html#SP21">&#167;21. Headings with extension dependencies</a></li><li><a href="6-hdn.html#SP25">&#167;25. The XML file</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. The hierarchy.</b>Headings in the source text correspond to <span class="extract"><span class="extract-syntax">HEADING_NT</span></span> nodes in syntax
trees, and mostly occur when the user has explicitly typed a heading such as:
</p>

<blockquote>
    <p>Part VII - The Ghost of the Aragon</p>
</blockquote>

<p class="commentary">Source text can make whatever headings it likes: no sequence is illegal. It
is not for Inform to decide on behalf of the author that it is eccentric to
place Section C before Section B, for instance. The author might be doing so
deliberately, to put the Chariot-race before the Baths, say. This is a
classic case where Inform trying to be too clever would annoy more often
than assist.
</p>

<p class="commentary">Nevertheless the sequence and relative hierarchy of headings is important.
Compare these two sequences:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">Part</span><span class="plain-syntax"> </span><span class="identifier-syntax">A</span><span class="plain-syntax">               </span><span class="identifier-syntax">Chapter</span><span class="plain-syntax"> </span><span class="identifier-syntax">A</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Chapter</span><span class="plain-syntax"> </span><span class="identifier-syntax">B</span><span class="plain-syntax">            </span><span class="identifier-syntax">Chapter</span><span class="plain-syntax"> </span><span class="identifier-syntax">B</span>
</pre>
<p class="commentary">In the first case, B is subordinate to A; in the second it is not, and this
affects the meaning of the program.
</p>

<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>Headings therefore have a numbered "level" of importance, with lower numbers
more important than higher. The hierarchy runs:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">Root</span><span class="plain-syntax"> = -1 &gt; </span><span class="identifier-syntax">Implied</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">Volume</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">Book</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">Part</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">Chapter</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">Section</span><span class="plain-syntax"> = </span><span class="constant-syntax">5</span>
</pre>
<p class="commentary">"Root" headings can be ignored &mdash; there's one at the root of the heading tree,
but it's only a hook to hang things from. "Implied" headings are inserted
to mark source file boundaries and the like, and aren't written by the author.
The importance of implied headings is that they ensure that every sentence
of source text ultimately falls under some heading.
</p>

<p class="commentary">The implementation allows even lower levels of subheading, 6 to 9, but these
are currently unused.
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">NO_HEADING_LEVELS</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>As an example, a sequence in the primary source text of (Chapter I, Book
Two, Section 5, Chapter I, Section 1, Chapter III) would be formed up into
the heading tree:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    (</span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="identifier-syntax">pseudo</span><span class="plain-syntax">-</span><span class="reserved-syntax">heading</span><span class="plain-syntax">)                </span><span class="identifier-syntax">level</span><span class="plain-syntax"> -1, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> -1</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Implied:</span><span class="plain-syntax"> </span><span class="identifier-syntax">inclusions</span><span class="plain-syntax">)           </span><span class="identifier-syntax">level</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Implied:</span><span class="plain-syntax"> </span><span class="identifier-syntax">Basic</span><span class="plain-syntax"> </span><span class="identifier-syntax">Inform</span><span class="plain-syntax">)         </span><span class="identifier-syntax">level</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span>
<span class="plain-syntax">            ...</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Implied:</span><span class="plain-syntax"> </span><span class="identifier-syntax">primary</span><span class="plain-syntax"> </span><span class="identifier-syntax">source</span><span class="plain-syntax"> </span><span class="identifier-syntax">text</span><span class="plain-syntax">)  </span><span class="identifier-syntax">level</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Chapter</span><span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="plain-syntax">                   </span><span class="identifier-syntax">level</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Book</span><span class="plain-syntax"> </span><span class="identifier-syntax">Two</span><span class="plain-syntax">                    </span><span class="identifier-syntax">level</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">Section</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">               </span><span class="identifier-syntax">level</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">Chapter</span><span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="plain-syntax">               </span><span class="identifier-syntax">level</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">Section</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">           </span><span class="identifier-syntax">level</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">Chapter</span><span class="plain-syntax"> </span><span class="identifier-syntax">III</span><span class="plain-syntax">             </span><span class="identifier-syntax">level</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Implied:</span><span class="plain-syntax"> </span><span class="identifier-syntax">inventions</span><span class="plain-syntax">)           </span><span class="identifier-syntax">level</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span>
</pre>
<p class="commentary">Note that the level of a heading is not the same thing as its depth in this
tree, which we call the "indentation", and there is no simple relationship
between the two numbers: see below for how it is calculated.
</p>

<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. Heading trees.</b>Enough theory: now some practice. Each syntax tree also has a heading tree,
with one "pseudo-heading" (at notional level \(-1\)) as root. All nodes are
instances of:
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">NEW_HEADING_TREE_SYNTAX_CALLBACK</span><span class="plain-syntax"> </span><a href="6-hdn.html#SP4" class="function-link"><span class="function-syntax">Headings::initialise_heading_tree</span></a>
<span class="definition-keyword">define</span> <span class="constant-syntax">HEADING_TREE_SYNTAX_TYPE</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">heading_tree</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">heading_tree</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">owning_syntax_tree</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> </span><span class="identifier-syntax">heading_root</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">assembled_at_least_once</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_indentation_above_level</span><span class="plain-syntax">[</span><span class="constant-syntax">NO_HEADING_LEVELS</span><span class="plain-syntax">];</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subordinates</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">heading</span></span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">damaged</span><span class="plain-syntax">; </span><span class="comment-syntax"> i.e., failed verification</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">heading_tree</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="function-syntax">Headings::root_of_tree</span><span class="plain-syntax">(</span><span class="reserved-syntax">heading_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">HT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> &amp;(</span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_root</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">heading_tree</span><span class="plain-syntax"> *</span><span class="function-syntax">Headings::initialise_heading_tree</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">heading_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">HT</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">heading_tree</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">owning_syntax_tree</span><span class="plain-syntax"> = </span><span class="identifier-syntax">T</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">assembled_at_least_once</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_root</span><span class="plain-syntax">.</span><span class="element-syntax">parent_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_root</span><span class="plain-syntax">.</span><span class="element-syntax">child_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_root</span><span class="plain-syntax">.</span><span class="element-syntax">next_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_root</span><span class="plain-syntax">.</span><span class="element-syntax">level</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_root</span><span class="plain-syntax">.</span><span class="element-syntax">indentation</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">NO_HEADING_LEVELS</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_indentation_above_level</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = -1;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">subordinates</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">heading</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">damaged</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">HT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure heading_tree is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>So now we calculate the indentation of a heading. The level \(\ell_n\) of a
heading depends only on its wording (or source file origin), but the indentation
of the \(n\)th heading, \(i_n\), depends on \((\ell_1, \ell_2, ..., \ell_n)\), the
sequence of all levels so far:
$$ i_n = i_m + 1 \qquad {\rm where}\qquad m = {\rm max} \lbrace j \mid 0\leq j &lt; n, \ell_j &lt; \ell_n \rbrace $$
where \(\ell_0 = i_0 = -1\), so that this set always contains 0 and is
therefore not empty. We deduce that
</p>

<ul class="items"><li>(a) \(i_1 = 0\) and thereafter \(i_n \geq 0\), since \(\ell_n\) is never negative again,
</li><li>(b) if \(\ell_k = \ell_{k+1}\) then \(i_k = i_{k+1}\), since the set over which
the maximum is taken is the same,
</li><li>(c) if \(\ell_{k+1} &gt; \ell_k\), a subheading of its predecessor, then
\(i_{k+1} = i_k + 1\), a single tab step outward.
</li></ul>
<p class="commentary">That establishes the other properties we wanted, and shows that \(i_n\) is
indeed the number of tab steps we should be determining.
</p>

<p class="commentary">Note that to calculate \(i_n\) we do not need the whole of \((\ell_1, ..., \ell_n)\):
we only need to remember the values of
$$ i_{m(K)},\qquad {\rm where}\qquad m(K) = {\rm max} \lbrace j \mid 0\leq j &lt; n, \ell_j &lt; K \rbrace $$
for each possible heading level \(K=0, 1, ..., 9\). This requires much less
storage: we call it the "last indentation above level \(K\)".
</p>

<p class="commentary">Which proves the correctness of the following innocent-looking function, called
on each heading in sequence:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::indent_from</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Headings::indent_from</span></span>:<br/><a href="6-hdn.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">heading_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">HT</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">level</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_indentation_above_level</span><span class="plain-syntax">[</span><span class="identifier-syntax">level</span><span class="plain-syntax">] + </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=</span><span class="identifier-syntax">level</span><span class="plain-syntax">+1; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">NO_HEADING_LEVELS</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_indentation_above_level</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. Heading metadata.</b>Each heading gets the following metadata:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">heading_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">owning_tree</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sentence_declaring</span><span class="plain-syntax">; </span><span class="comment-syntax"> if any: file starts are undeclared</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">source_location</span><span class="plain-syntax"> </span><span class="identifier-syntax">start_location</span><span class="plain-syntax">; </span><span class="comment-syntax"> first word under this heading is here</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">level</span><span class="plain-syntax">; </span><span class="comment-syntax"> 0 for Volume (highest) to 5 for Section (lowest)</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">; </span><span class="comment-syntax"> in a hierarchical listing</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">index_definitions_made_under_this</span><span class="plain-syntax">; </span><span class="comment-syntax"> for instance, global variables made here?</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">for_release</span><span class="plain-syntax">; </span><span class="comment-syntax"> include this material in a release version?</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">omit_material</span><span class="plain-syntax">; </span><span class="comment-syntax"> if set, simply ignore all of this</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">use_with_or_without</span><span class="plain-syntax">; </span><span class="comment-syntax"> if TRUE, use with the extension; if FALSE, without</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">holds_dialogue</span><span class="plain-syntax">; </span><span class="comment-syntax"> if TRUE, contains dialogue in a different format</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">for_use_with</span><span class="plain-syntax">; </span><span class="comment-syntax"> e.g. "for use with ... by ..."</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">in_place_of_text</span><span class="plain-syntax">; </span><span class="comment-syntax"> e.g. "in place of ... in ... by ..."</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">heading_text</span><span class="plain-syntax">; </span><span class="comment-syntax"> once provisos have been stripped away</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">external_file</span><span class="plain-syntax">; </span><span class="comment-syntax"> e.g. "see ..."</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">source_file</span><span class="plain-syntax"> *</span><span class="identifier-syntax">external_file_read</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">external_file_loaded</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="identifier-syntax">list_of_contents</span><span class="plain-syntax">; </span><span class="comment-syntax"> tagged names defined under this</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">noun</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_in_list_of_contents</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parent_heading</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">child_heading</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_heading</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">omit_from_tree</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">heading_compilation_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">compilation_data</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">heading</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure heading is accessed in 1/sm, 3/bs2, 6/inc and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>It is guaranteed that this will be called once for each heading (except the
pseudo-heading, which doesn't count) in sequence order:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="function-syntax">Headings::new</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Headings::new</span></span>:<br/><a href="6-hdn.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">level</span><span class="plain-syntax">, </span><span class="identifier-syntax">source_location</span><span class="plain-syntax"> </span><span class="identifier-syntax">sl</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">heading</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">owning_tree</span><span class="plain-syntax"> = </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">omit_from_tree</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">list_of_contents</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_in_list_of_contents</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_release</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">; </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">omit_material</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">index_definitions_made_under_this</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">use_with_or_without</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">in_place_of_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">external_file</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">external_file_read</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">external_file_loaded</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_use_with</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sentence_declaring</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">holds_dialogue</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">start_location</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sl</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">level</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">indentation</span><span class="plain-syntax"> = </span><a href="6-hdn.html#SP5" class="function-link"><span class="function-syntax">Headings::indent_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">, </span><span class="identifier-syntax">level</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="reserved-syntax">heading</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">subordinates</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">compilation_data</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CompletionModule::new_compilation_data</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Declarations.</b>The following callback function is called by <a href="../syntax-module/index.html" class="internal">syntax</a> each time a new
<span class="extract"><span class="extract-syntax">HEADING_NT</span></span> node is created in the syntax tree for a project. It has to
return <span class="extract"><span class="extract-syntax">TRUE</span></span> or <span class="extract"><span class="extract-syntax">FALSE</span></span> to say whether sentences falling under the current
heading should be included in the project's source text. (For instance,
sentences under a heading with the disclaimer "(for Glulx only)" will not be
included if the target virtual machine on this run of Inform is the Z-machine.)
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">NEW_HEADING_SYNTAX_CALLBACK</span><span class="plain-syntax"> </span><a href="6-hdn.html#SP8" class="function-link"><span class="function-syntax">Headings::place</span></a>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::place</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="reserved-syntax">inform_project</span><span class="plain-syntax"> *</span><span class="identifier-syntax">proj</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><a href="6-hdn.html#SP11" class="function-link"><span class="function-syntax">Headings::attach</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">, (</span><span class="identifier-syntax">proj</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">proj</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_copy</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">are_we_releasing</span><span class="plain-syntax"> = </span><a href="5-ps2.html#SP19" class="function-link"><span class="function-syntax">Projects::currently_releasing</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">proj</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_release</span><span class="plain-syntax"> == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">are_we_releasing</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_release</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">are_we_releasing</span><span class="plain-syntax"> == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">omit_material</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b><a href="5-ps2.html#SP37" class="internal">Projects::read_source_text_for</a> also constructs implied super-headings
which do not originate in the sentence-breaker, and which therefore need a
different way in. (These are never skipped.)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::place_implied_level_0</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Headings::place_implied_level_0</span></span>:<br/>Project Services - <a href="5-ps2.html#SP37_1">&#167;37.1</a>, <a href="5-ps2.html#SP37_3">&#167;37.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_copy</span><span class="plain-syntax"> *</span><span class="identifier-syntax">for_copy</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><a href="6-hdn.html#SP11" class="function-link"><span class="function-syntax">Headings::attach</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">for_copy</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">heading_level_ANNOT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">implied_heading_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>Either way, we can always get back from the parse node to the heading:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="function-syntax">Headings::from_node</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Headings::from_node</span></span>:<br/><a href="6-hdn.html#SP20">&#167;20</a>, <a href="6-hdn.html#SP24">&#167;24</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Node::get_embodying_heading</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>So, then, each <span class="extract"><span class="extract-syntax">HEADING_NT</span></span> node in the parse tree produces a call to this
function, which attaches a new <a href="6-hdn.html#SP6" class="internal">heading</a> object to it, and populates that
with the result of parsing any caveats in its wording.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work_identified</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> temporary variable during parsing below</span>

<span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="function-syntax">Headings::attach</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Headings::attach</span></span>:<br/><a href="6-hdn.html#SP8">&#167;8</a>, <a href="6-hdn.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_copy</span><span class="plain-syntax"> *</span><span class="identifier-syntax">for_copy</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pn</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Wordings::empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">))))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"heading at textless node"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">) != </span><span class="identifier-syntax">HEADING_NT</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"declared a non-HEADING node as heading"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">heading_level_ANNOT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">level</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">level</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">NO_HEADING_LEVELS</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"impossible level"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><a href="6-hdn.html#SP7" class="function-link"><span class="function-syntax">Headings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">level</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::location</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">)));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Node::set_embodying_heading</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="6-hdn.html#SP11_1" class="named-paragraph-link"><span class="named-paragraph">Parse heading text for release or other stipulations</span><span class="named-paragraph-number">11.1</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;h-&gt;</span><span class="element-syntax">indentation</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">HEADINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"  "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">HEADINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Attach heading %W level %d ind %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">), </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">indentation</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">assembled_at_least_once</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><a href="6-hdn.html#SP14" class="function-link"><span class="function-syntax">Headings::assemble_tree</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">for_copy</span><span class="plain-syntax">); </span><span class="comment-syntax"> to include new heading: unlikely but possible</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11_1" class="paragraph-anchor"></a><b>&#167;11.1. </b>And these are the aforementioned caveats:
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PLATFORM_UNMET_HQ</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">PLATFORM_MET_HQ</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">NOT_FOR_RELEASE_HQ</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">FOR_RELEASE_ONLY_HQ</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">UNINDEXED_HQ</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">USE_WITH_HQ</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">USE_WITHOUT_HQ</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">IN_PLACE_OF_HQ</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">DIALOGUE_HQ</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">EXTERNAL_HQ</span><span class="plain-syntax"> </span><span class="constant-syntax">9</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse heading text for release or other stipulations</span><span class="named-paragraph-number">11.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;heading-qualifier&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PLATFORM_UNMET_HQ:</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">omit_material</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NOT_FOR_RELEASE_HQ:</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_release</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FOR_RELEASE_ONLY_HQ:</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_release</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNINDEXED_HQ:</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">index_definitions_made_under_this</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">USE_WITH_HQ:</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">use_with_or_without</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">USE_WITHOUT_HQ:</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">use_with_or_without</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">DIALOGUE_HQ:</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax"> != </span><span class="constant-syntax">5</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                    </span><span class="reserved-syntax">copy_error</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CE</span><span class="plain-syntax"> = </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SYNTAX_CE</span><span class="plain-syntax">, </span><span class="constant-syntax">DialogueOnSectionsOnly_SYNERROR</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><a href="2-ce.html#SP3" class="function-link"><span class="function-syntax">CopyErrors::supply_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CE</span><span class="plain-syntax">, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                }</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">holds_dialogue</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">IN_PLACE_OF_HQ:</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">use_with_or_without</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">in_place_of_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;extension-qualifier&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTERNAL_HQ:</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">external_file</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;bracketed-heading-qualifier&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">Word::dequote</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">external_file</span><span class="plain-syntax">));</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">inform_project</span><span class="plain-syntax"> *</span><span class="identifier-syntax">proj</span><span class="plain-syntax"> = </span><a href="4-pbm.html#SP2" class="function-link"><span class="function-syntax">ProjectBundleManager::from_copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">for_copy</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">proj</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">leaf</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">leaf</span><span class="plain-syntax">, </span><span class="string-syntax">"%W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">external_file</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><a href="5-ps2.html#SP12" class="function-link"><span class="function-syntax">Projects::add_heading_source</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">proj</span><span class="plain-syntax">, </span><span class="identifier-syntax">leaf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">leaf</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                }</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;heading-qualifier&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_use_with</span><span class="plain-syntax"> = </span><span class="identifier-syntax">work_identified</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP11">&#167;11</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>When a heading has been found, we repeatedly try to match it against
&lt;heading-qualifier&gt; to see if it ends with text telling us what to do with
the source text it governs. For example,
</p>

<blockquote>
    <p>Section 21 - Frogs (unindexed) (not for Glulx)</p>
</blockquote>

<p class="commentary">would match twice, first registering the VM requirement, then the unindexedness.
</p>

<p class="commentary">It's an unfortunate historical quirk that the unbracketed qualifiers are
allowed; they should probably be withdrawn.
</p>

<p class="commentary">Properly speaking the annotation "(dialogue)" should be recognised only if
the dialogue feature is active, but there are timing reasons not to do this:
headings are parsed before the set of active compiler features for a project
is determined.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="function-syntax">&lt;heading-qualifier&gt;</span>
<span class="plain-syntax">    ... ( </span><span class="function-syntax">&lt;bracketed-heading-qualifier&gt;</span><span class="plain-syntax"> ) |</span>
<span class="plain-syntax">    ... </span><span class="identifier-syntax">not</span><span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> </span><span class="identifier-syntax">release</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    ... </span><span class="reserved-syntax">for</span><span class="plain-syntax"> </span><span class="identifier-syntax">release</span><span class="plain-syntax"> </span><span class="identifier-syntax">only</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    ... </span><span class="identifier-syntax">unindexed</span>

<span class="function-syntax">&lt;bracketed-heading-qualifier&gt;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">not</span><span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> </span><span class="identifier-syntax">release</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> </span><span class="identifier-syntax">release</span><span class="plain-syntax"> </span><span class="identifier-syntax">only</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">unindexed</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">dialogue</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">dialog</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">dialogue</span><span class="plain-syntax"> </span><span class="identifier-syntax">during</span><span class="plain-syntax"> ... |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">dialog</span><span class="plain-syntax"> </span><span class="identifier-syntax">during</span><span class="plain-syntax"> ... |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">see</span><span class="plain-syntax"> { </span><span class="function-syntax">&lt;quoted-text&gt;</span><span class="plain-syntax"> } |</span>
<span class="plain-syntax">    </span><span class="function-syntax">&lt;platform-qualifier&gt;</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="function-syntax">&lt;extension-qualifier&gt;</span>

<span class="function-syntax">&lt;platform-qualifier&gt;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> </span><span class="function-syntax">&lt;platform-identifier&gt;</span><span class="plain-syntax"> </span><span class="identifier-syntax">only</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">not</span><span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> </span><span class="function-syntax">&lt;platform-identifier&gt;</span>

<span class="function-syntax">&lt;platform-identifier&gt;</span>
<span class="plain-syntax">    </span><span class="function-syntax">&lt;language-element&gt;</span><span class="plain-syntax"> </span><span class="identifier-syntax">language</span><span class="plain-syntax"> </span><span class="identifier-syntax">element</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    ...... </span><span class="identifier-syntax">language</span><span class="plain-syntax"> </span><span class="identifier-syntax">element</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="function-syntax">&lt;current-virtual-machine&gt;</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    ......</span>

<span class="function-syntax">&lt;extension-qualifier&gt;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> </span><span class="identifier-syntax">use</span><span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span class="plain-syntax"> </span><span class="function-syntax">&lt;extension-identifier&gt;</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> </span><span class="identifier-syntax">use</span><span class="plain-syntax"> </span><span class="identifier-syntax">without</span><span class="plain-syntax"> </span><span class="function-syntax">&lt;extension-identifier&gt;</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">not</span><span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> </span><span class="identifier-syntax">use</span><span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span class="plain-syntax"> </span><span class="function-syntax">&lt;extension-identifier&gt;</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">in</span><span class="plain-syntax"> </span><span class="identifier-syntax">place</span><span class="plain-syntax"> </span><span class="identifier-syntax">of</span><span class="plain-syntax"> ( </span><span class="function-syntax">&lt;quoted-text&gt;</span><span class="plain-syntax"> ) </span><span class="identifier-syntax">in</span><span class="plain-syntax"> </span><span class="function-syntax">&lt;extension-identifier&gt;</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">in</span><span class="plain-syntax"> </span><span class="identifier-syntax">place</span><span class="plain-syntax"> </span><span class="identifier-syntax">of</span><span class="plain-syntax"> ...... </span><span class="identifier-syntax">in</span><span class="plain-syntax"> </span><span class="function-syntax">&lt;extension-identifier&gt;</span>

<span class="function-syntax">&lt;extension-identifier&gt;</span>
<span class="plain-syntax">    ...... </span><span class="identifier-syntax">by</span><span class="plain-syntax"> ......</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12_1" class="paragraph-anchor"></a><b>&#167;12.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_UnknownLanguageElement problem</span><span class="named-paragraph-number">12.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">copy_error</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CE</span><span class="plain-syntax"> = </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SYNTAX_CE</span><span class="plain-syntax">, </span><span class="constant-syntax">UnknownLanguageElement_SYNERROR</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-ce.html#SP3" class="function-link"><span class="function-syntax">CopyErrors::supply_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CE</span><span class="plain-syntax">, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP12">&#167;12</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP12_2" class="paragraph-anchor"></a><b>&#167;12.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_UnknownVirtualMachine problem</span><span class="named-paragraph-number">12.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">copy_error</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CE</span><span class="plain-syntax"> = </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SYNTAX_CE</span><span class="plain-syntax">, </span><span class="constant-syntax">UnknownVirtualMachine_SYNERROR</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-ce.html#SP3" class="function-link"><span class="function-syntax">CopyErrors::supply_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CE</span><span class="plain-syntax">, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP12">&#167;12</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP12_3" class="paragraph-anchor"></a><b>&#167;12.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Set for-use-with extension identifier</span><span class="named-paragraph-number">12.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">exft</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">exfa</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">TW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;extension-identifier&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">AW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;extension-identifier&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">exft</span><span class="plain-syntax">, </span><span class="string-syntax">"%+W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TW</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">exfa</span><span class="plain-syntax">, </span><span class="string-syntax">"%+W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">AW</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">work_identified</span><span class="plain-syntax"> = </span><a href="2-wrk.html#SP2" class="function-link"><span class="function-syntax">Works::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">extension_genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">exft</span><span class="plain-syntax">, </span><span class="identifier-syntax">exfa</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">exft</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">exfa</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    ==&gt; { </span><span class="identifier-syntax">R</span><span class="plain-syntax">[0] + </span><span class="constant-syntax">4</span><span class="plain-syntax">, - };</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP12">&#167;12</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b>This nonterminal matches any description of a virtual machine, and produces
the result <span class="extract"><span class="extract-syntax">TRUE</span></span> if the VM we are building for fits that description, <span class="extract"><span class="extract-syntax">FALSE</span></span>
otherwise.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="function-syntax">&lt;current-virtual-machine&gt;</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;virtual-machine&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vms</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">compatibility_specification</span><span class="plain-syntax"> *) </span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        ==&gt; { </span><span class="identifier-syntax">Compatibility::test</span><span class="plain-syntax">(</span><span class="identifier-syntax">vms</span><span class="plain-syntax">, </span><a href="1-ic.html#SP11" class="function-link"><span class="function-syntax">Supervisor::current_vm</span></a><span class="plain-syntax">()), - };</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        ==&gt; { </span><span class="identifier-syntax">fail</span><span class="plain-syntax"> </span><span class="identifier-syntax">nonterminal</span><span class="plain-syntax"> };</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. The heading tree.</b>Until <a href="6-hdn.html#SP14" class="internal">Headings::assemble_tree</a> runs, the <a href="6-hdn.html#SP6" class="internal">heading</a> nodes listed as belonging
to the heading tree are not in fact formed up into a tree structure.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::assemble_tree</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Headings::assemble_tree</span></span>:<br/><a href="6-hdn.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_copy</span><span class="plain-syntax"> *</span><span class="identifier-syntax">for_copy</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="6-hdn.html#SP14_1" class="named-paragraph-link"><span class="named-paragraph">Disassemble the whole heading tree to a pile of twigs</span><span class="named-paragraph-number">14.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="reserved-syntax">heading</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">subordinates</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">omit_from_tree</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="6-hdn.html#SP14_2" class="named-paragraph-link"><span class="named-paragraph">If h is outside the tree, make it a child of the pseudo-heading</span><span class="named-paragraph-number">14.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="6-hdn.html#SP14_3" class="named-paragraph-link"><span class="named-paragraph">If h is held in an external file, move those headings to it</span><span class="named-paragraph-number">14.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="6-hdn.html#SP14_4" class="named-paragraph-link"><span class="named-paragraph">Run through subsequent equal or subordinate headings to move them downward</span><span class="named-paragraph-number">14.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">assembled_at_least_once</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><a href="6-hdn.html#SP16" class="function-link"><span class="function-syntax">Headings::verify_heading_tree</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifndef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax">    </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::list_attached_errors</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="identifier-syntax">for_copy</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">SourceProblems::issue_problems_arising</span><span class="plain-syntax">(</span><span class="identifier-syntax">for_copy</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14_1" class="paragraph-anchor"></a><b>&#167;14.1. </b>It's possible to call <a href="6-hdn.html#SP14" class="internal">Headings::assemble_tree</a> more than once, to allow
for late news coming in (see <a href="6-hdn.html#SP11" class="internal">Headings::attach</a> above), so we always begin by
disassembling the tree, and then we can be sure that we start from nothing.
</p>

<p class="commentary">Note that the pseudo-heading used as a root of the tree is not in the list
of subordinates. Everything else is.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Disassemble the whole heading tree to a pile of twigs</span><span class="named-paragraph-number">14.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_root</span><span class="plain-syntax">.</span><span class="element-syntax">child_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_root</span><span class="plain-syntax">.</span><span class="element-syntax">parent_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_root</span><span class="plain-syntax">.</span><span class="element-syntax">next_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="reserved-syntax">heading</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">subordinates</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">omit_from_tree</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP14">&#167;14</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP14_2" class="paragraph-anchor"></a><b>&#167;14.2. </b>The idea of the heading loop is that when we place a heading, we also place
subsequent headings of lesser or equal status until we cannot do so any longer.
That means that if we reach h and find that it has no parent, it must be
subordinate to no earlier heading: thus, it must be attached to the pseudo-heading
at the top of the tree.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">If h is outside the tree, make it a child of the pseudo-heading</span><span class="named-paragraph-number">14.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent_heading</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">omit_from_tree</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><a href="6-hdn.html#SP15" class="function-link"><span class="function-syntax">Headings::move_below</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">, &amp;(</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_root</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP14">&#167;14</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP14_3" class="paragraph-anchor"></a><b>&#167;14.3. </b>A complication is that the source text is read out of conceptual sequence
when headings referring to external files are run into. Because of that, if
we have a heading:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">Chapter</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span><span class="plain-syntax"> - </span><span class="identifier-syntax">Into</span><span class="plain-syntax"> </span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="identifier-syntax">Woods</span><span class="plain-syntax"> (</span><span class="identifier-syntax">see</span><span class="plain-syntax"> </span><span class="string-syntax">"woods.i7"</span><span class="plain-syntax">)</span>
</pre>
<p class="commentary">and if we then have further headings inside the file <span class="extract"><span class="extract-syntax">woods.i7</span></span>, those
further headings <span class="extract"><span class="extract-syntax">h2</span></span> won't be adjacent to the original heading <span class="extract"><span class="extract-syntax">h</span></span> in
the list. So we fix this up here.
</p>

<p class="commentary">There is a nameless level zero heading marking the change of source file:
we remove that. We also have to throw problems if we find, say, a Book
heading inside a file which is supposed to contain a Chapter.
</p>

<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">HeadingTooGreat_SYNERROR</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">If h is held in an external file, move those headings to it</span><span class="named-paragraph-number">14.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">external_file_read</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">h2</span><span class="plain-syntax">, </span><span class="reserved-syntax">heading</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">subordinates</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">start_location</span><span class="plain-syntax">.</span><span class="identifier-syntax">file_of_origin</span><span class="plain-syntax"> == </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">external_file_read</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">h2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">omit_from_tree</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                    </span><span class="reserved-syntax">copy_error</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CE</span><span class="plain-syntax"> = </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SYNTAX_CE</span><span class="plain-syntax">, </span><span class="constant-syntax">HeadingTooGreat_SYNERROR</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><a href="2-ce.html#SP3" class="function-link"><span class="function-syntax">CopyErrors::supply_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CE</span><span class="plain-syntax">, </span><span class="identifier-syntax">h2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sentence_declaring</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">for_copy</span><span class="plain-syntax">, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">h2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">omit_from_tree</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">                    </span><a href="6-hdn.html#SP15" class="function-link"><span class="function-syntax">Headings::move_below</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">h2</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">h2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">indentation</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">                }</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP14">&#167;14</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP14_4" class="paragraph-anchor"></a><b>&#167;14.4. </b>Note that the following could be summed up as "move subsequent headings as
deep in the tree as we can see they need to be from h's perspective alone".
This isn't always the final position. For instance, given the sequence
Volume 1, Chapter I, Section A, Chapter II, the tree is adjusted twice:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">when</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Volume</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">:        </span><span class="identifier-syntax">then</span><span class="plain-syntax"> </span><span class="identifier-syntax">when</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Chapter</span><span class="plain-syntax"> </span><span class="identifier-syntax">I:</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Volume</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">                  </span><span class="identifier-syntax">Volume</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Chapter</span><span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="plain-syntax">                 </span><span class="identifier-syntax">Chapter</span><span class="plain-syntax"> </span><span class="identifier-syntax">I</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Section</span><span class="plain-syntax"> </span><span class="identifier-syntax">A</span><span class="plain-syntax">                     </span><span class="identifier-syntax">Section</span><span class="plain-syntax"> </span><span class="identifier-syntax">A</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Chapter</span><span class="plain-syntax"> </span><span class="identifier-syntax">II</span><span class="plain-syntax">                </span><span class="identifier-syntax">Chapter</span><span class="plain-syntax"> </span><span class="identifier-syntax">II</span>
</pre>
<p class="commentary">since Section A is demoted twice, once by Volume 1, then by Chapter I.
(This algorithm would in principle be quadratic in the number of headings if
the possible depth of the tree were unbounded &mdash; every heading might have to
demote every one of its successors &mdash; but since the depth is at most 9, it
runs in linear time.)
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Run through subsequent equal or subordinate headings to move them downward</span><span class="named-paragraph-number">14.4</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subseq</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">subseq</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEXT_OBJECT</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="reserved-syntax">heading</span><span class="plain-syntax">); </span><span class="comment-syntax"> start from the next heading in source</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">subseq</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">subseq</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax">); </span><span class="comment-syntax"> for a run with level below or equal h</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">subseq</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEXT_OBJECT</span><span class="plain-syntax">(</span><span class="identifier-syntax">subseq</span><span class="plain-syntax">, </span><span class="reserved-syntax">heading</span><span class="plain-syntax">)) { </span><span class="comment-syntax"> in source declaration order</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">subseq</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax"> == </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax">) { </span><span class="comment-syntax"> a heading of equal status ends the run...</span>
<span class="plain-syntax">            </span><a href="6-hdn.html#SP15" class="function-link"><span class="function-syntax">Headings::move_below</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">subseq</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent_heading</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> ...becoming h's sibling</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><a href="6-hdn.html#SP15" class="function-link"><span class="function-syntax">Headings::move_below</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">subseq</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">); </span><span class="comment-syntax"> all lesser headings in the run become h's children</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP14">&#167;14</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. </b>The above function, then, calls <span class="extract"><span class="extract-syntax">Headings::move_below</span></span> to attach a heading
to the tree as a child of a given parent:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::move_below</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Headings::move_below</span></span>:<br/><a href="6-hdn.html#SP14_2">&#167;14.2</a>, <a href="6-hdn.html#SP14_3">&#167;14.3</a>, <a href="6-hdn.html#SP14_4">&#167;14.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ch</span><span class="plain-syntax">, </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pa</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">former_pa</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ch</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent_heading</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">former_pa</span><span class="plain-syntax"> == </span><span class="identifier-syntax">pa</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="6-hdn.html#SP15_1" class="named-paragraph-link"><span class="named-paragraph">Detach ch from the heading tree if it is already there</span><span class="named-paragraph-number">15.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ch</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pa</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="6-hdn.html#SP15_2" class="named-paragraph-link"><span class="named-paragraph">Add ch to the end of the list of children of pa</span><span class="named-paragraph-number">15.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15_1" class="paragraph-anchor"></a><b>&#167;15.1. </b>If ch is present in the tree, it must have a parent, unless it is the
pseudo-heading: but the latter can never be moved, so it isn't. Therefore
we can remove ch by striking it out from the children list of the parent.
(Any children which ch has, grandchildren so to speak, come with it.)
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Detach ch from the heading tree if it is already there</span><span class="named-paragraph-number">15.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">former_pa</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">former_pa</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child_heading</span><span class="plain-syntax"> == </span><span class="identifier-syntax">ch</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">former_pa</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ch</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_heading</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sib</span><span class="plain-syntax"> = </span><span class="identifier-syntax">former_pa</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child_heading</span><span class="plain-syntax">; </span><span class="identifier-syntax">sib</span><span class="plain-syntax">; </span><span class="identifier-syntax">sib</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sib</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_heading</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sib</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_heading</span><span class="plain-syntax"> == </span><span class="identifier-syntax">ch</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">sib</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ch</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_heading</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                    </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ch</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP15">&#167;15</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP15_2" class="paragraph-anchor"></a><b>&#167;15.2. </b>Two cases: the new parent is initially childless, or it isn't.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add ch to the end of the list of children of pa</span><span class="named-paragraph-number">15.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pa</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child_heading</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">pa</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ch</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sib</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pa</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child_heading</span><span class="plain-syntax">; </span><span class="identifier-syntax">sib</span><span class="plain-syntax">; </span><span class="identifier-syntax">sib</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sib</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_heading</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sib</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_heading</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">sib</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_heading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ch</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP15">&#167;15</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. Verifying the heading tree.</b>We have now, in effect, computed the indentation value of each heading twice,
by two entirely different methods: first by the mathematical argument above,
then by observing that it is the depth in the heading tree. Seeing if
these two methods have given the same answer provides a convenient check on
our working.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::verify_heading_tree</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Headings::verify_heading_tree</span></span>:<br/><a href="6-hdn.html#SP14">&#167;14</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><a href="6-hdn.html#SP16" class="function-link"><span class="function-syntax">Headings::verify_heading_tree_r</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        &amp;(</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_root</span><span class="plain-syntax">), &amp;(</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_root</span><span class="plain-syntax">), -1);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">damaged</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"heading tree failed to verify"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::verify_heading_tree_r</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">root</span><span class="plain-syntax">, </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">h</span><span class="plain-syntax"> != </span><span class="identifier-syntax">root</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">depth</span><span class="plain-syntax"> != </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">indentation</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">damaged</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$H\n*** indentation should be %d ***\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><a href="6-hdn.html#SP16" class="function-link"><span class="function-syntax">Headings::verify_heading_tree_r</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">root</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child_heading</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">+1);</span>
<span class="plain-syntax">    </span><a href="6-hdn.html#SP16" class="function-link"><span class="function-syntax">Headings::verify_heading_tree_r</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">root</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_heading</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. Falling under headings.</b>Given a position in the source code, or an excerpt of source text, which
heading does it fall under?
</p>

<p class="commentary">This question matters since the parsing of noun phrases is affected by
that choice of heading: to Inform, headings provide something analogous to
the scope of local variables in a conventional programming language. It also
affects problem messages.
</p>

<p class="commentary">Because every file has an Implied (0) heading registered at line 1, the loop
in the following function is guaranteed to return a valid heading provided
the original source location is well formed (i.e., has a non-null source
file and a line number of at least 1).
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="function-syntax">Headings::of_location</span><span class="plain-syntax">(</span><span class="identifier-syntax">source_location</span><span class="plain-syntax"> </span><span class="identifier-syntax">sl</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sl</span><span class="plain-syntax">.</span><span class="identifier-syntax">file_of_origin</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_BACKWARDS_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="reserved-syntax">heading</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">sl</span><span class="plain-syntax">.</span><span class="identifier-syntax">file_of_origin</span><span class="plain-syntax"> == </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">start_location</span><span class="plain-syntax">.</span><span class="identifier-syntax">file_of_origin</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">sl</span><span class="plain-syntax">.</span><span class="element-syntax">line_number</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">start_location</span><span class="plain-syntax">.</span><span class="element-syntax">line_number</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unable to determine the heading level of source material"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="function-syntax">Headings::of_wording</span><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="6-hdn.html#SP17" class="function-link"><span class="function-syntax">Headings::of_location</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::location</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. Miscellaneous other services.</b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::indexed</span><span class="plain-syntax">(</span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> definitions made nowhere are normally indexed</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">index_definitions_made_under_this</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">inform_extension</span><span class="plain-syntax"> *</span><span class="function-syntax">Headings::get_extension_containing</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Headings::get_extension_containing</span></span>:<br/><a href="6-hdn.html#SP22">&#167;22</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">h</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">start_location</span><span class="plain-syntax">.</span><span class="identifier-syntax">file_of_origin</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="5-es.html#SP16" class="function-link"><span class="function-syntax">Extensions::corresponding_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">start_location</span><span class="plain-syntax">.</span><span class="identifier-syntax">file_of_origin</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. </b>Although Implied (0) headings do have text, contrary to the implication of
the function here, this text is only what happens to be first in the file,
or else is something supplied by <a href="index.html" class="internal">supervisor</a> purely to make the debugging
log comprehensible: it isn't a heading typed as such by the user, which is all
that we are interested in for this purpose. So we send back a null word range.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::get_text</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Headings::get_text</span></span>:<br/><a href="6-hdn.html#SP20">&#167;20</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">h</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_text</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. </b>Whence:
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">WORDING_FOR_HEADING_NODE_PROBLEMS_CALLBACK</span><span class="plain-syntax"> </span><a href="6-hdn.html#SP20" class="function-link"><span class="function-syntax">Headings::wording_for_heading_node</span></a>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::wording_for_heading_node</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="6-hdn.html#SP19" class="function-link"><span class="function-syntax">Headings::get_text</span></a><span class="plain-syntax">(</span><a href="6-hdn.html#SP10" class="function-link"><span class="function-syntax">Headings::from_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. Headings with extension dependencies.</b>If the content under a heading depended on a VM not in use, or was marked
not for release in a release run, we were able to exclude it just by
skipping. The same cannot be done when a heading says that it should be
used only if a given extension is, or is not, being used, because when
the heading is created we don't yet know which extensions are included.
But when the following is called, we do know that.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::satisfy_dependencies</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Headings::satisfy_dependencies</span></span>:<br/>Project Services - <a href="5-ps2.html#SP37_4">&#167;37.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inform_project</span><span class="plain-syntax"> *</span><span class="identifier-syntax">proj</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_copy</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="reserved-syntax">heading</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">subordinates</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">use_with_or_without</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><a href="6-hdn.html#SP22" class="function-link"><span class="function-syntax">Headings::satisfy_individual_heading_dependency</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">proj</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b>And now the code to check an individual heading's usage. This whole
thing is carefully timed so that we can still afford to cut up and rearrange
the parse tree on quite a large scale, and that's just what we do.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::satisfy_individual_heading_dependency</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Headings::satisfy_individual_heading_dependency</span></span>:<br/><a href="6-hdn.html#SP21">&#167;21</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inform_project</span><span class="plain-syntax"> *</span><span class="identifier-syntax">proj</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_copy</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax"> = </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_use_with</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">loaded</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">work</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">inform_extension</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="reserved-syntax">inform_extension</span><span class="plain-syntax">, </span><span class="identifier-syntax">proj</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">extensions_included</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-wrk.html#SP9" class="function-link"><span class="function-syntax">Works::match</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">, </span><span class="identifier-syntax">work</span><span class="plain-syntax">))</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">loaded</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">HEADINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"SIHD on $H: loaded %d: annotation %d: %W: %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="identifier-syntax">loaded</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sentence_declaring</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">suppress_heading_dependencies_ANNOT</span><span class="plain-syntax">),</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">in_place_of_text</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">use_with_or_without</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">in_place_of_text</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">S</span><span class="plain-syntax"> = </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">in_place_of_text</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sentence_declaring</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">suppress_heading_dependencies_ANNOT</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;quoted-text&gt;(h-&gt;</span><span class="element-syntax">in_place_of_text</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">Word::dequote</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">));</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">inchar32_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::word_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">));</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">S</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::feed_C_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">loaded</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="6-hdn.html#SP22_1" class="named-paragraph-link"><span class="named-paragraph">Can't replace heading in an unincluded extension</span><span class="named-paragraph-number">22.1</span></a></span>
<span class="plain-syntax">            </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">h2</span><span class="plain-syntax">, </span><span class="reserved-syntax">heading</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">subordinates</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                    </span><span class="reserved-syntax">inform_extension</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ext</span><span class="plain-syntax"> = </span><a href="6-hdn.html#SP18" class="function-link"><span class="function-syntax">Headings::get_extension_containing</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">h2</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">h2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_text</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax">                        (</span><span class="identifier-syntax">Wordings::match_perhaps_quoted</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">h2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_text</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax">                        (</span><a href="2-wrk.html#SP9" class="function-link"><span class="function-syntax">Works::match</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ext</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">, </span><span class="identifier-syntax">work</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">                        </span><span class="identifier-syntax">found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax"> != </span><span class="identifier-syntax">h2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                            </span><span class="named-paragraph-container code-font"><a href="6-hdn.html#SP22_3" class="named-paragraph-link"><span class="named-paragraph">Can't replace heading unless level matches</span><span class="named-paragraph-number">22.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">                        </span><a href="6-hdn.html#SP23" class="function-link"><span class="function-syntax">Headings::excise_material_under</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">h2</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                        </span><a href="6-hdn.html#SP23" class="function-link"><span class="function-syntax">Headings::excise_material_under</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="identifier-syntax">h2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sentence_declaring</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                        </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                    }</span>
<span class="plain-syntax">                }</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">found</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="6-hdn.html#SP22_2" class="named-paragraph-link"><span class="named-paragraph">Can't find heading in the given extension</span><span class="named-paragraph-number">22.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">use_with_or_without</span><span class="plain-syntax"> != </span><span class="identifier-syntax">loaded</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><a href="6-hdn.html#SP23" class="function-link"><span class="function-syntax">Headings::excise_material_under</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22_1" class="paragraph-anchor"></a><b>&#167;22.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Can't replace heading in an unincluded extension</span><span class="named-paragraph-number">22.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">copy_error</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CE</span><span class="plain-syntax"> = </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SYNTAX_CE</span><span class="plain-syntax">, </span><span class="constant-syntax">HeadingInPlaceOfUnincluded_SYNERROR</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-ce.html#SP3" class="function-link"><span class="function-syntax">CopyErrors::supply_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CE</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sentence_declaring</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-ce.html#SP3" class="function-link"><span class="function-syntax">CopyErrors::supply_work</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CE</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_use_with</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP22">&#167;22</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. </b>To excise, we simply prune the heading's contents from the parse tree,
though optionally grafting them to another node rather than discarding them
altogether.
</p>

<p class="commentary">Any heading which is excised is marked so that it won't have its own
dependencies checked. This clarifies several cases, and in particular ensures
that if Chapter X is excised then a subordinate Section Y cannot live on by
replacing something elsewhere (which would effectively delete the content
elsewhere).
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::excise_material_under</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Headings::excise_material_under</span></span>:<br/><a href="6-hdn.html#SP22">&#167;22</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_copy</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transfer_to</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">HEADINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Excision under $H\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">hpn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sentence_declaring</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sentence_declaring</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"stipulations on a non-sentence heading"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">in_place_of_text</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h2</span><span class="plain-syntax"> = </span><a href="6-hdn.html#SP24" class="function-link"><span class="function-syntax">Headings::find_dependent_heading</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">hpn</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h2</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="6-hdn.html#SP23_1" class="named-paragraph-link"><span class="named-paragraph">Can't replace heading subordinate to another replaced heading</span><span class="named-paragraph-number">23.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>

<span class="plain-syntax">    </span><a href="6-hdn.html#SP24" class="function-link"><span class="function-syntax">Headings::suppress_dependencies</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">hpn</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">transfer_to</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">hpn</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">)) </span><span class="identifier-syntax">SyntaxTree::graft</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">hpn</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, </span><span class="identifier-syntax">transfer_to</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">hpn</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="function-syntax">Headings::find_dependent_heading</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Headings::find_dependent_heading</span></span>:<br/><a href="6-hdn.html#SP23">&#167;23</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pn</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">) == </span><span class="identifier-syntax">HEADING_NT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><a href="6-hdn.html#SP10" class="function-link"><span class="function-syntax">Headings::from_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">h</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">in_place_of_text</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><a href="6-hdn.html#SP10" class="function-link"><span class="function-syntax">Headings::from_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::suppress_dependencies</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Headings::suppress_dependencies</span></span>:<br/><a href="6-hdn.html#SP23">&#167;23</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">) == </span><span class="identifier-syntax">HEADING_NT</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">suppress_heading_dependencies_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><a href="6-hdn.html#SP24" class="function-link"><span class="function-syntax">Headings::suppress_dependencies</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23_1" class="paragraph-anchor"></a><b>&#167;23.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Can't replace heading subordinate to another replaced heading</span><span class="named-paragraph-number">23.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">copy_error</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CE</span><span class="plain-syntax"> = </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SYNTAX_CE</span><span class="plain-syntax">, </span><span class="constant-syntax">HeadingInPlaceOfSubordinate_SYNERROR</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-ce.html#SP3" class="function-link"><span class="function-syntax">CopyErrors::supply_works</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CE</span><span class="plain-syntax">, </span><span class="identifier-syntax">h2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_use_with</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_use_with</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-ce.html#SP3" class="function-link"><span class="function-syntax">CopyErrors::supply_nodes</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CE</span><span class="plain-syntax">, </span><span class="identifier-syntax">h2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sentence_declaring</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sentence_declaring</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP23">&#167;23</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP22_2" class="paragraph-anchor"></a><b>&#167;22.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Can't find heading in the given extension</span><span class="named-paragraph-number">22.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">vt</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">vt</span><span class="plain-syntax">, </span><span class="string-syntax">"unspecified, that is, the extension didn't have a version number"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inform_extension</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="reserved-syntax">inform_extension</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-wrk.html#SP9" class="function-link"><span class="function-syntax">Works::match</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_use_with</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">vt</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">VersionNumbers::to_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">vt</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">version</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">copy_error</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CE</span><span class="plain-syntax"> = </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SYNTAX_CE</span><span class="plain-syntax">, </span><span class="constant-syntax">HeadingInPlaceOfUnknown_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">vt</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-ce.html#SP3" class="function-link"><span class="function-syntax">CopyErrors::supply_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CE</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sentence_declaring</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-ce.html#SP3" class="function-link"><span class="function-syntax">CopyErrors::supply_work</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CE</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_use_with</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-ce.html#SP3" class="function-link"><span class="function-syntax">CopyErrors::supply_wording</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CE</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">in_place_of_text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">vt</span><span class="plain-syntax">)</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP22">&#167;22</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP22_3" class="paragraph-anchor"></a><b>&#167;22.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Can't replace heading unless level matches</span><span class="named-paragraph-number">22.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">copy_error</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CE</span><span class="plain-syntax"> = </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SYNTAX_CE</span><span class="plain-syntax">, </span><span class="constant-syntax">UnequalHeadingInPlaceOf_SYNERROR</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-ce.html#SP3" class="function-link"><span class="function-syntax">CopyErrors::supply_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CE</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sentence_declaring</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP22">&#167;22</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>&#167;25. The XML file.</b>This is provided as a convenience to the application using Inform, which may want
to have a pull-down menu or similar gadget allowing the user to jump to a given
heading. This tells the interface where every heading is, thus saving it from
having to parse the source.
</p>

<p class="commentary">The property list contains a single dictionary, whose keys are the numbers
0, 1, 2, ..., \(n-1\), where there are \(n\) headings in all.
</p>

<p class="commentary">A special key, the only non-numerical one, called "Application Version", contains
the Inform build number.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Headings::write_as_XML</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> </span><span class="identifier-syntax">xf_struct</span><span class="plain-syntax">; </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> = &amp;</span><span class="identifier-syntax">xf_struct</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">STREAM_OPEN_TO_FILE</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">UTF8_ENC</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Problems::fatal_on_file</span><span class="plain-syntax">(</span><span class="string-syntax">"Can't open headings file"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">        #</span><span class="identifier-syntax">ifndef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Errors::fatal_with_file</span><span class="plain-syntax">(</span><span class="string-syntax">"can't open headings file"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">heading</span><span class="plain-syntax"> *</span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="6-hdn.html#SP25_1" class="named-paragraph-link"><span class="named-paragraph">Write DTD indication for XML headings file</span><span class="named-paragraph-number">25.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;plist version=\"1.0\"&gt;&lt;dict&gt;\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;key&gt;Application Version&lt;/key&gt;&lt;string&gt;%B (build %B)&lt;/string&gt;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">, </span><span class="reserved-syntax">heading</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">headings</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">subordinates</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;key&gt;%d&lt;/key&gt;&lt;dict&gt;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="6-hdn.html#SP25_2" class="named-paragraph-link"><span class="named-paragraph">Write the dictionary of properties for a single heading</span><span class="named-paragraph-number">25.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;/dict&gt;\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;/dict&gt;&lt;/plist&gt;\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">STREAM_CLOSE</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP25_1" class="paragraph-anchor"></a><b>&#167;25.1. </b>We use a convenient Apple DTD:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Write DTD indication for XML headings file</span><span class="named-paragraph-number">25.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\n"</span>
<span class="plain-syntax">        </span><span class="string-syntax">"&lt;!DOCTYPE plist PUBLIC \"-</span><span class="comment-syntax">Apple Computer//DTD PLIST 1.0//EN\" "</span>
<span class="string-syntax">        "</span><span class="plain-syntax">\</span><span class="string-syntax">"http:</span><span class="comment-syntax">www.apple.com/DTDs/PropertyList-1.0.dtd\"&gt;\n");</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP25">&#167;25</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP25_2" class="paragraph-anchor"></a><b>&#167;25.2. </b>Note that a level of 0, and a title of <span class="extract"><span class="extract-syntax">--</span></span>, signifies a File (0) level
heading: external tools can probably ignore such records. Similarly, it is
unlikely that they will ever see a record without a "Filename" key, but they
are optional all the same.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Write the dictionary of properties for a single heading</span><span class="named-paragraph-number">25.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">start_location</span><span class="plain-syntax">.</span><span class="identifier-syntax">file_of_origin</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;key&gt;Filename&lt;/key&gt;&lt;string&gt;%f&lt;/string&gt;\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">TextFromFiles::get_filename</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">start_location</span><span class="plain-syntax">.</span><span class="identifier-syntax">file_of_origin</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;key&gt;Line&lt;/key&gt;&lt;integer&gt;%d&lt;/integer&gt;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">start_location</span><span class="plain-syntax">.</span><span class="element-syntax">line_number</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_text</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;key&gt;Title&lt;/key&gt;&lt;string&gt;%+W&lt;/string&gt;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heading_text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;key&gt;Title&lt;/key&gt;&lt;string&gt;--&lt;/string&gt;\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;key&gt;Level&lt;/key&gt;&lt;integer&gt;%d&lt;/integer&gt;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">level</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;key&gt;Indentation&lt;/key&gt;&lt;integer&gt;%d&lt;/integer&gt;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">indentation</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-hdn.html#SP25">&#167;25</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="6-st.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-sm.html">1</a></li><li class="progresschapter"><a href="2-gnr.html">2</a></li><li class="progresschapter"><a href="3-bg.html">3</a></li><li class="progresschapter"><a href="4-em.html">4</a></li><li class="progresschapter"><a href="5-es.html">5</a></li><li class="progresscurrentchapter">6</li><li class="progresssection"><a href="6-st.html">st</a></li><li class="progresscurrent">hdn</li><li class="progresssection"><a href="6-tof.html">tof</a></li><li class="progresssection"><a href="6-inc.html">inc</a></li><li class="progresssection"><a href="6-cs.html">cs</a></li><li class="progresssection"><a href="6-vmg.html">vmg</a></li><li class="progresschapter"><a href="7-tm.html">7</a></li><li class="progressnext"><a href="6-tof.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

